package com.zzyl.service.impl;

import cn.hutool.crypto.digest.BCrypt;
import cn.hutool.json.JSONUtil;
import com.zzyl.constant.CacheConstant;
import com.zzyl.dto.LoginDto;
import com.zzyl.entity.Resource;
import com.zzyl.entity.User;
import com.zzyl.enums.BasicEnum;
import com.zzyl.exception.BaseException;
import com.zzyl.mapper.ResourceMapper;
import com.zzyl.mapper.UserMapper;
import com.zzyl.properties.JwtTokenManagerProperties;
import com.zzyl.properties.UserPublicPathProperties;
import com.zzyl.service.LoginService;
import com.zzyl.utils.JwtUtil;
import com.zzyl.vo.UserVo;
import org.apache.ibatis.annotations.Select;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;

import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;

@Service
public class LoginServiceImpl implements LoginService {
    /**
     * 用户登录
     *
     * @param loginDto
     * @return
     */
    @Autowired
    private UserMapper userMapper;
    @Autowired
    private ResourceMapper resourceMapper;
    @Autowired
    private UserPublicPathProperties userPublicPathProperties;
    @Autowired
    private StringRedisTemplate redisTemplate;
    @Autowired
    private JwtTokenManagerProperties jwt;

    @Override
    public UserVo login(LoginDto loginDto) {
        String username = loginDto.getUsername();
        UserVo user = userMapper.selectByUserId(username);
        //1用户是否存在
        if (user == null) {
            throw new BaseException(BasicEnum.LOGIN_FAIL);
        }
        //用户是否禁用
        if ("1".equals(user.getDataState())) {
            throw new BaseException(BasicEnum.COUNT_NOT_ENABLE);
        }
        //获取用户资源列表
        //私有
        List<Resource> resource = resourceMapper.selectVoByUserId(user.getId());
        List<String> requestPathAll = resource.stream().map(Resource::getRequestPath).collect(Collectors.toList());
        //共有
        List<String> publicAccessUrls = userPublicPathProperties.getPublicAccessUrls();
        requestPathAll.addAll(publicAccessUrls);
        //用户密码是否正确
        if (!BCrypt.checkpw(loginDto.getPassword(), user.getPassword())) {
            throw new BaseException(BasicEnum.PASSWORD_ERROR);
        }
        //密码置空
        user.setPassword(null);
        //生成token
        Map<String, Object> hmp = new HashMap<>();
        hmp.put("currentUser", JSONUtil.toJsonStr(user));
        int time = jwt.getTtl();
        user.setUserToken(JwtUtil.createJWT(jwt.getBase64EncodedSecretKey(), time, hmp));
        //存入redid
        redisTemplate.opsForValue().set(CacheConstant.USER_PUBLIC_RESOURCE + user.getId(), JSONUtil.toJsonStr(requestPathAll), time / 1000, TimeUnit.SECONDS);
        //返回
        return user;
    }
}
